﻿#define _CRT_SECURE_NO_WARNINGS 1

#include"snake.h"

void setpos(int x, int y)
{
	COORD pos = { x, y };
	HANDLE houtput = GetStdHandle(STD_OUTPUT_HANDLE);
	SetConsoleCursorPosition(houtput, pos);
}

//打印欢迎界面
void WelcomeGame()
{
	//界面1
	setpos(40, 20);
	printf("欢迎来到贪吃蛇小游戏\n");
	setpos(40, 35);
	system("pause");
	system("cls");
	//界面2
	setpos(30, 20);
	printf("用↑、↓、←、→分别控制蛇的移动，F1为加速，F2为减速\n");
	setpos(30, 21);
	printf("加速可以获得更高的分数。");
	setpos(30, 35);
	system("pause");
	system("cls");
}


//打印地图
void CreatMap()
{
	int i = 0;
	//上
	for (; i <= 36; i++)
	{
		//wprintf(L"%lc", L'□');
		wprintf(L"%lc", L'□');
	}
	//下
	setpos(0, 26);
	for (i = 0; i <= 36; i++)
	{
		wprintf(L"%lc", L'□');
	}

	//左
	for (i = 1; i <= 25; i++)
	{
		setpos(0, i);
		wprintf(L"%lc", L'□');
	}
	//右

	for (i = 1; i <= 25; i++)
	{
		setpos(72, i);
		wprintf(L"%lc", L'□');
	}
	//功能
	setpos(30, 31);
	printf("用↑、↓、←、→分别控制蛇的移动，F1为加速，F2为减速\n");
	setpos(30, 32);
	printf("加速可以获得更高的分数。");
	system("pause");
}

//蛇的初始化
void InitSnake(pSnake ps)
{
	pSnakeNode cur = NULL;
	for (int i = 0; i < 5; i++)
	{
		cur = (pSnakeNode)malloc(sizeof(SnakeNode));
		if (cur == NULL)
		{
			perror("InitSnake()::maiioc()");
			return;
		}
		cur->next = NULL;
		cur->x = POS_X + 2 * i;
		cur->y = POS_Y;
		if (ps->_psnake == NULL)
		{
			ps->_psnake = cur;
		}
		else
		{
			cur->next = ps->_psnake;
			ps->_psnake = cur;
		}
	}

	cur = ps->_psnake;
	while (cur)
	{
		setpos(cur->x, cur->y);
		wprintf(L"%lc", L'●');
		cur = cur->next;
	}

	//设置贪吃蛇的属行
	ps->_dir = RIGHT;//默认向右
	ps->_sorce = 0;
	ps->_foodweight = 10;
	ps->_sleeptime = 200;//单位毫秒
	ps->_status = OK;
	
}

//创造食物
void CreatFood(pSnake ps)
{
	int x = 0;
	int y = 0;

again:
	do
	{
		x = 2 + rand() % 71;
		y = 1 + rand() % 25;
	} while (x % 2 != 0);

	pSnakeNode cur = ps->_psnake;
	while (cur)
	{
		if (cur->x == x && cur->y == y)
		{
			goto again;
		}
		cur = cur->next;
	}

	 pSnakeNode pFood= (pSnakeNode)malloc(sizeof(SnakeNode));
	if (pFood == NULL)
	{
		perror("CreatFood():maiioc()");
		return;
	}
	
	pFood->x = x;
	pFood->y = y;
	pFood->next = NULL;
	setpos(x, y);
	wprintf(L"%lc", L'★');
	ps->_pfood = pFood;
	
}

void GameStart(pSnake ps)
{
	system("mode con cols=100 lines=40");
	system("title 贪吃蛇");

	//获得句柄
	HANDLE houtput = GetStdHandle(STD_OUTPUT_HANDLE);
	//隐藏光标
	CONSOLE_CURSOR_INFO cursorinfo;
	GetConsoleCursorInfo(houtput, &cursorinfo);
	cursorinfo.bVisible = false;
	SetConsoleCursorInfo(houtput, &cursorinfo);

	//打印欢迎界面
	WelcomeGame();

	//打印地图
	CreatMap();//这里是函数的调用不是声明

	//蛇的初始化
	InitSnake(ps);

	//食物
	CreatFood(ps);
	
}



//判断按键
#define		KEY_PRESS(vk)    ((GetAsyncKeyState(vk) & 0x1) ? 1 : 0)

//暂停
void pause()
{
	while (1)
	{
		Sleep(300);
		if (KEY_PRESS(VK_SPACE))
			break;
	}
}

void EatFood(pSnakeNode psn, pSnake ps)
{
	psn->next = ps->_psnake;
	ps->_psnake = psn;
	pSnakeNode cur = psn;
	while (cur)
	{
		setpos(cur->x, cur->y);
		wprintf(L"%lc", L'●');
		cur = cur->next;
	}

	ps->_sorce += ps->_foodweight;
	free(ps->_pfood);
	ps->_pfood = NULL;

	CreatFood(ps);
}

void NoEatFood(pSnakeNode psn, pSnake ps)
{
	psn->next = ps->_psnake;
	ps->_psnake = psn;
	pSnakeNode cur = psn;

	while (cur->next->next)
	{
		setpos(cur->next->x, cur->next->y);
		wprintf(L"%lc", L'●');
		cur = cur->next;
	}


	setpos(cur->next->x, cur->next->y);
	printf("  ");
	free(cur->next);
	cur->next = NULL;
	
}

//贪吃蛇移动
void SnakeMove(pSnake ps)
{
	//贪吃蛇下一个节点
	pSnakeNode pNextNode = (pSnakeNode)malloc(sizeof(SnakeNode));
	if (pNextNode == NULL)
	{
		perror("SnakeMove()::malloc()");
		return;
	}
	switch (ps->_dir)
	{
	case UP:
		pNextNode->x = ps->_psnake->x;
		pNextNode->y = ps->_psnake->y - 1;
		break;
	case DOWN:
		pNextNode->x = ps->_psnake->x;
		pNextNode->y = ps->_psnake->y + 1;
		break;
	case LEFT:
		pNextNode->x = ps->_psnake->x - 2;
		pNextNode->y = ps->_psnake->y;
		break;
	case RIGHT:
		pNextNode->x = ps->_psnake->x + 2;
		pNextNode->y = ps->_psnake->y;
		break;
	}

	if(ps->_pfood->x == pNextNode->x && ps->_pfood->y == pNextNode->y)
	{
		EatFood(pNextNode, ps);
		pNextNode = NULL;
	}
	else
	{
		NoEatFood(pNextNode, ps);
	}

}

void Kill_By_Wall(pSnake ps)
{
	if (ps->_psnake->x == 0 || ps->_psnake->x == 72 ||
		ps->_psnake->y == 0 || ps->_psnake->y == 26)
	{
		ps->_status = KILL_BY_WALL;
	}
}

void Kill_By_SELF(pSnake ps)
{
	pSnakeNode cur = ps->_psnake->next;
	while (cur)
	{
		if (cur->x == ps->_psnake->x && cur->y == ps->_psnake->y)
		{
			ps->_status = KILKL_BY_SELF;
		}
		cur = cur->next;
	}
	
}


//游戏运行
void GameRun(pSnake ps)
{
	do
	{
		setpos(85, 20);
		printf("总分数：%d", ps->_sorce);
		setpos(80, 21);
		printf("每个食物的分值为：%d", ps->_foodweight);

		if (KEY_PRESS(VK_UP) && ps->_dir != DOWN)
		{
			ps->_dir = UP;
		}
		else if(KEY_PRESS(VK_DOWN) && ps->_dir != UP)
		{
			ps->_dir = DOWN;
		}
		else if (KEY_PRESS(VK_LEFT) && ps->_dir != RIGHT)
		{
			ps->_dir = LEFT;
		}
		else if (KEY_PRESS(VK_RIGHT) && ps->_dir != LEFT)
		{
			ps->_dir = RIGHT;
		}
		else if (KEY_PRESS(VK_SPACE))
		{
			//暂停
			pause();
		}
		else if (KEY_PRESS(VK_ESCAPE))
		{
			ps->_status = END_NOMAL;
		}
		else if (KEY_PRESS(VK_F1))
		{
			//加速
			if (ps->_sleeptime > 80)
			{
				ps->_sleeptime -= 40;
				ps->_foodweight += 2;
			}
			else
			{
				ps->_sleeptime = 200;
				ps->_foodweight = 10;
			}
		}
		else if (KEY_PRESS(VK_F2))
		{
			//减速
			if (ps->_sleeptime < 320)
			{
				ps->_sleeptime += 40;
				ps->_foodweight -= 2;
			}
			else
			{
				ps->_sleeptime = 200;
				ps->_foodweight = 10;
			}
		}

		SnakeMove(ps);

		Sleep(ps->_sleeptime);
		Kill_By_Wall(ps);

		Kill_By_SELF(ps);

	} while (ps->_status == OK);

}



//游戏善后工作
void GameEnd(pSnake ps)
{
	setpos(44, 20);
	switch(ps->_status)
	{
	case END_NOMAL:
		printf("您主动结束游戏\n");
		break;
	case KILL_BY_WALL:
		printf("您撞墙了，游戏结束\n");
		break;
	case KILKL_BY_SELF:
		printf("您撞到自己了，游戏结束\n");
		break;

	}
	setpos(44, 21);
	printf("您的分数是：%d", ps->_sorce);

	//释放空间
	pSnakeNode cur = ps->_psnake;
	while (cur)
	{
		pSnakeNode del = cur;
		cur = cur->next;
		free(del);
	}
}